﻿using System;
using System.Text;
using System.Web;
using System.Configuration;
using System.IO;
using MvcShop.Core.Helper;
using MvcShop.Extensions;
using MvcShop.MVC.Extension;
using MvcShop.Core.Architecture.Configuration;

namespace MvcShop.MVC.Handlers.Resources
{
    public class ResourcesHandler:BaseHandler
    {
        public ResourcesHandler() 
        {
            configuration = (IConfigurationManager)MvcApplication.Container["core"];
        }

        public ResourcesHandler(IConfigurationManager configurationManager)
        {
            configuration = configurationManager;
        }


        public IConfigurationManager configuration
        {
            get;
            set;
        }

        public override void ProcessRequest(HttpContextBase context)
        {
            string resourcesName = context.Request.QueryString["name"];

            if (!string.IsNullOrEmpty(resourcesName))
            {
                ResourcesElement setting = GetSetting(configuration, resourcesName);

                if (setting != null)
                {
                    var resources = GetResources(context, setting);

                    if (resources != null)
                    {

                        HttpResponseBase response = context.Response;

                        // Set the content type
                        response.ContentType = setting.ContentType;

                        // 压缩
                        if (setting.Compress)
                        {
                            context.CompressResponse();
                        }

                        // 输出请求
                        using (StreamWriter sw = new StreamWriter(response.OutputStream))
                        {
                            sw.Write(resources.Content);
                        }

                        // 缓存
                        if (setting.CacheDurationInDays > 0)
                        {
                            if (setting.GenerateETag)
                            {
                                response.Cache.SetETag(resources.ETag);
                            }

                            context.CacheResponseFor(TimeSpan.FromDays(setting.CacheDurationInDays));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 获取配置
        /// </summary>
        /// <param name="configuration">配置数据的编程模型类</param>
        /// <param name="resourcesName">配置节点名</param>
        /// <returns>ResourcesElement类配置对象</returns>
        private static ResourcesElement GetSetting(IConfigurationManager configuration, string resourcesName)
        {
            ResourcesSettingsSection settings = (ResourcesSettingsSection)configuration.GetSection<ResourcesSettingsSection>(ResourcesSettingsSection.SectionName);
            ResourcesElement setting = settings.Resourcess[resourcesName];
            ResourcesElement clone = null;

            if (setting != null)
            {
                clone = new ResourcesElement
                {
                    Name = setting.Name,
                    ContentType = setting.ContentType,
                    Version = setting.Version,
                    CacheDurationInDays = setting.CacheDurationInDays,
                    Directory = setting.Directory,
                    Files = setting.Files
                };

                // 设置压缩属性值
                if ((clone.Compress == ResourcesSettingsSection.DefaultCompress) && (settings.Compress != ResourcesSettingsSection.DefaultCompress))
                {
                    clone.Compress = settings.Compress;
                }

                // 设置缓存属性值
                if ((clone.CacheDurationInDays == ResourcesSettingsSection.DefaultCacheDurationInDays) && (settings.CacheDurationInDays != ResourcesSettingsSection.DefaultCacheDurationInDays))
                {
                    clone.CacheDurationInDays = settings.CacheDurationInDays;
                }

                // 设置版本属性值
                if (string.IsNullOrEmpty(clone.Version))
                {
                    clone.Version = settings.Version;
                }
            }

            return clone;
        }
        /// <summary>
        /// 获取请求资源
        /// </summary>
        /// <param name="context"></param>
        /// <param name="setting">ResourcesElement配置节</param>
        /// <returns>HandlerCacheItem类(请求资源)</returns>
        private HandlerCacheItem GetResources(HttpContextBase context, ResourcesElement setting)
        {
            string key = String.Format("cache:{0}", setting.Name);
            HandlerCacheItem hci;

            Cache.TryGet(key, out hci);

            //hci = null;
            if (hci == null)
            {
                string[] files = setting.Files.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                if (files.Length > 0)
                {
                    StringBuilder contentBuilder = new StringBuilder();

                    for (int i = 0; i < files.Length; i++)
                    {
                        string file = context.Server.MapPath(Path.Combine(setting.Directory, files[i]));
                        string fileContent = File.ReadAllText(file);

                        if (!string.IsNullOrEmpty(fileContent))
                        {
                            contentBuilder.AppendLine(fileContent);
                            contentBuilder.AppendLine();
                        }
                    }

                    string content = contentBuilder.ToString();

                    
                    if (!string.IsNullOrEmpty(content))
                    {
                        hci = new HandlerCacheItem { Content = content };

                        if ((setting.CacheDurationInDays > 0) && (!Cache.Contains(key)))
                        {
                            Cache.Set(key, hci, SystemTime.Now().AddDays(setting.CacheDurationInDays));
                        }
                    }
                }
            }
            return hci;
        }
    }
}
